package edu.hawaii.halealohacli.command;

import java.io.IOException;
import java.util.GregorianCalendar;
import java.util.Timer;
import java.util.TimerTask;
import javax.xml.datatype.XMLGregorianCalendar;
import org.wattdepot.client.BadXmlException;
import org.wattdepot.client.MiscClientException;
import org.wattdepot.client.NotAuthorizedException;
import org.wattdepot.client.ResourceNotFoundException;
import org.wattdepot.client.WattDepotClient;
import org.wattdepot.resource.sensordata.jaxb.SensorData;

/**
 * This command prints out a timestamp and the current power for [tower | lounge] every [interval]
 * seconds. [interval] is an optional integer greater than 0 and defaults to 10 seconds.
 * 
 * @author Jason Yeo
 */
public class MonitorPower extends TimerTask {
  private String source;
  private int interval = 10;
  private WattDepotClient client;
  private double getPower = 0.0;

  /**
   * Constructor for 2 arguments.
   * 
   * @param s String representing source
   * @param c WattDepotClient client
   */
  public MonitorPower(String s, WattDepotClient c) {
    this.source = s;
    this.client = c;
  }

  /**
   * Constructor for 3 arguments.
   * 
   * @param s String representing source
   * @param c WattDepotClient client
   * @param i interval
   */
  public MonitorPower(String s, WattDepotClient c, int i) {
    this.source = s;
    this.client = c;
    this.interval = i;
  }

  /**
   * outputs the current power of the specified source at the specified interval.
   */
  public void printResults() {
    try {
      System.out.println("Monitoring power for " + this.source + " at every " + this.interval
          + " seconds. Press enter to stop.");
      Timer timer = new Timer();
      timer.scheduleAtFixedRate(this, interval * 1000, interval * 1000);
      while (System.in.available() == 0) {
        run();
        Thread.sleep(interval * 1000);
      }
      timer.cancel();
      Thread.sleep(200);
      System.out.println("Terminated monitoring");
    }
    catch (IllegalArgumentException e) {
      System.out.println("Error in arguments");
    }
    catch (IllegalStateException e) {
      System.out.println("Error in timer");
    }
    catch (InterruptedException e) {
      System.out.println("Error in threads");
    }
    catch (IOException e) {
      System.out.println("IO error");
    }
  }

  /**
   * run method for the interval loop.
   */
  public void run() {
    GregorianCalendar today = new GregorianCalendar();
    SensorData data = null;
    XMLGregorianCalendar timestamp = null;
    double currentPower;
    try {
      data = client.getLatestSensorData(source);
      timestamp = data.getTimestamp();

      currentPower = client.getPowerConsumed(source, timestamp);
      currentPower = currentPower / 1000;
      getPower = currentPower;

      // System.out.println(today.getTime() + ": " + currentPower + " kW");
      System.out.format("%s: %.1f kW\n", today.getTime(), currentPower);
    }
    catch (NotAuthorizedException e1) {
      e1.printStackTrace();
    }
    catch (ResourceNotFoundException e1) {
      e1.printStackTrace();
    }
    catch (BadXmlException e1) {
      e1.printStackTrace();
    }
    catch (MiscClientException e1) {
      e1.printStackTrace();
    }
  }

  /**
   * getter method to return the source string.
   * 
   * @return source
   */
  public String getSource() {
    return this.source;
  }

  /**
   * getter method to return the current power for the tower or lounge.
   * 
   * @return getPower
   */
  public double getPower() {
    return this.getPower;
  }
}